"""API适配器基础类"""

import time
from typing import Dict, Any, Optional, Union
import requests
from .exceptions import (
    RequestError,
    AuthenticationError,
    RateLimitError,
    ValidationError,
    APIError
)


class BaseAPI:
    """API适配器基础类"""
    
    def __init__(self,
                 base_url: str,
                 timeout: int = 30,
                 max_retries: int = 3,
                 retry_delay: int = 1):
        """
        初始化API适配器
        
        Args:
            base_url: API基础URL
            timeout: 请求超时时间（秒）
            max_retries: 最大重试次数
            retry_delay: 重试间隔（秒）
        """
        self.base_url = base_url.rstrip('/')
        self.timeout = timeout
        self.max_retries = max_retries
        self.retry_delay = retry_delay
        self.session = requests.Session()
        
    def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
        """
        处理API响应
        
        Args:
            response: requests.Response对象
            
        Returns:
            解析后的响应数据
            
        Raises:
            APIError: API调用错误
        """
        try:
            # 尝试JSON解析
            data = response.json()
        except ValueError:
            # 非JSON响应
            data = {"content": response.text}
        
        # 检查状态码
        if response.status_code >= 400:
            if response.status_code == 401:
                raise AuthenticationError("认证失败", response.status_code, response)
            elif response.status_code == 429:
                raise RateLimitError("请求频率过高", response.status_code, response)
            elif response.status_code == 400:
                error_msg = data.get('message', data.get('error', '参数错误'))
                raise ValidationError(error_msg, response.status_code, response)
            else:
                error_msg = data.get('message', data.get('error', f'请求失败: {response.status_code}'))
                raise RequestError(error_msg, response.status_code, response)
        
        return data
    
    def _request(self,
                 method: str,
                 endpoint: str,
                 params: Optional[Dict[str, Any]] = None,
                 data: Optional[Union[Dict[str, Any], str]] = None,
                 json_data: Optional[Dict[str, Any]] = None,
                 headers: Optional[Dict[str, str]] = None,
                 files: Optional[Dict[str, Any]] = None,
                 **kwargs) -> Dict[str, Any]:
        """
        发送HTTP请求
        
        Args:
            method: HTTP方法 (GET, POST, PUT, DELETE等)
            endpoint: API端点（相对于base_url）
            params: URL查询参数
            data: 表单数据
            json_data: JSON数据
            headers: 请求头
            files: 文件上传
            **kwargs: 其他requests参数
            
        Returns:
            解析后的响应数据
        """
        url = f"{self.base_url}/{endpoint.lstrip('/')}"
        
        # 合并请求头
        request_headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }
        if headers:
            request_headers.update(headers)
        
        # 准备请求参数
        request_kwargs = {
            'timeout': self.timeout,
            'headers': request_headers,
            **kwargs
        }
        
        if params:
            request_kwargs['params'] = params
        if data:
            request_kwargs['data'] = data
        if json_data:
            request_kwargs['json'] = json_data
        if files:
            request_kwargs['files'] = files
            # 文件上传时移除Content-Type，让requests自动处理
            if 'Content-Type' in request_headers:
                del request_headers['Content-Type']
        
        # 重试机制
        for attempt in range(self.max_retries):
            try:
                response = self.session.request(method, url, **request_kwargs)
                return self._handle_response(response)
            except (requests.RequestException, APIError) as e:
                # 最后一次尝试失败时抛出异常
                if attempt == self.max_retries - 1:
                    raise
                
                # 处理特定错误的重试逻辑
                if isinstance(e, RateLimitError):
                    # 频率限制错误，等待更长时间
                    wait_time = self.retry_delay * (attempt + 1) * 2
                else:
                    wait_time = self.retry_delay * (attempt + 1)
                
                time.sleep(wait_time)
    
    def get(self,
            endpoint: str,
            params: Optional[Dict[str, Any]] = None,
            headers: Optional[Dict[str, str]] = None,
            **kwargs) -> Dict[str, Any]:
        """
        发送GET请求
        
        Args:
            endpoint: API端点
            params: URL查询参数
            headers: 请求头
            **kwargs: 其他参数
            
        Returns:
            解析后的响应数据
        """
        return self._request('GET', endpoint, params=params, headers=headers, **kwargs)
    
    def post(self,
             endpoint: str,
             data: Optional[Union[Dict[str, Any], str]] = None,
             json_data: Optional[Dict[str, Any]] = None,
             params: Optional[Dict[str, Any]] = None,
             headers: Optional[Dict[str, str]] = None,
             files: Optional[Dict[str, Any]] = None,
             **kwargs) -> Dict[str, Any]:
        """
        发送POST请求
        
        Args:
            endpoint: API端点
            data: 表单数据
            json_data: JSON数据
            params: URL查询参数
            headers: 请求头
            files: 文件上传
            **kwargs: 其他参数
            
        Returns:
            解析后的响应数据
        """
        return self._request(
            'POST',
            endpoint,
            params=params,
            data=data,
            json_data=json_data,
            headers=headers,
            files=files,
            **kwargs
        )
    
    def put(self,
            endpoint: str,
            data: Optional[Union[Dict[str, Any], str]] = None,
            json_data: Optional[Dict[str, Any]] = None,
            params: Optional[Dict[str, Any]] = None,
            headers: Optional[Dict[str, str]] = None,
            **kwargs) -> Dict[str, Any]:
        """
        发送PUT请求
        
        Args:
            endpoint: API端点
            data: 表单数据
            json_data: JSON数据
            params: URL查询参数
            headers: 请求头
            **kwargs: 其他参数
            
        Returns:
            解析后的响应数据
        """
        return self._request(
            'PUT',
            endpoint,
            params=params,
            data=data,
            json_data=json_data,
            headers=headers,
            **kwargs
        )
    
    def delete(self,
               endpoint: str,
               params: Optional[Dict[str, Any]] = None,
               headers: Optional[Dict[str, str]] = None,
               **kwargs) -> Dict[str, Any]:
        """
        发送DELETE请求
        
        Args:
            endpoint: API端点
            params: URL查询参数
            headers: 请求头
            **kwargs: 其他参数
            
        Returns:
            解析后的响应数据
        """
        return self._request('DELETE', endpoint, params=params, headers=headers, **kwargs)
    
    def close(self):
        """关闭会话"""
        if hasattr(self, 'session'):
            self.session.close()